package com.powernode.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.powernode.domain.Prod;
import com.powernode.domain.ProdComm;
import com.powernode.domain.ProdTagReference;
import com.powernode.domain.Sku;
import com.powernode.dto.ChangeDto;
import com.powernode.dto.EsChange;
import com.powernode.dto.SkuChang;
import com.powernode.service.*;
import com.powernode.mapper.ProdMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 *
 */
@Service
public class ProdServiceImpl extends ServiceImpl<ProdMapper, Prod>
        implements ProdService {
    @Autowired
    private ProdMapper prodMapper;

    @Autowired
    private SkuService skuService;

    @Autowired
    private ProdCommService prodCommService;

    @Autowired
    private ProdTagReferenceService prodTagReferenceService;


    @Override
    public Page<Prod> getProdPage(Page<Prod> page, Prod prod) {
        //根据产品名和状态查询
        return prodMapper.selectPage(page, new LambdaQueryWrapper<Prod>()
                //模糊查询产品名
                .like(StringUtils.hasText(prod.getProdName()), Prod::getProdName, prod.getProdName())
                //状态查询
                .eq(!ObjectUtils.isEmpty(prod.getStatus()), Prod::getStatus, prod.getStatus()));
    }

    @Override
    @Transactional
    public void addProd(Prod prod) {
        prod.setCreateTime(new Date());
        //由于数据库保存的是字符串
        prod.setDeliveryMode(JSON.toJSONString(prod.getDeliveryMode()));
        //插入商品
        prodMapper.insert(prod);
        //得到sku数据
        List<Sku> skuList = prod.getSkuList();
        skuList.forEach(sku -> {
            sku.setProdId(prod.getProdId());
            sku.setRecTime(new Date());
            sku.setUpdateTime(new Date());
        });
        skuService.saveBatch(skuList);
        //设置标签id
        List<Long> tagList = prod.getTagList();
        List<ProdTagReference> list = new ArrayList<>();
        tagList.forEach(tagId -> {
            ProdTagReference prodTagReference = new ProdTagReference();
            prodTagReference.setCreateTime(new Date());
            prodTagReference.setTagId(tagId);
            prodTagReference.setProdId(prod.getProdId());
            list.add(prodTagReference);
        });
        prodTagReferenceService.saveBatch(list);
    }

    //用于查询为上架的prod商品
    @Override
    public List<Prod> selectDbData(Page<Prod> prodPage, Date start, Date end) {
        prodPage = prodMapper.selectPage(prodPage, new LambdaQueryWrapper<Prod>()
                .in(Prod::getStatus, 0)
                .between(!ObjectUtils.isEmpty(start) && !ObjectUtils.isEmpty(end), Prod::getCreateTime, start, end));

        List<Prod> records = prodPage.getRecords();
        //es中是有商品标签的 查询所所有商品标签
        if (!CollectionUtils.isEmpty(records)) {
            //获取到所有商品id
            List<Long> prodIds = records.stream().map(Prod::getProdId).collect(Collectors.toList());
            //查询这些商品锁具有的所有标签
            List<ProdTagReference> tagList = prodTagReferenceService.list(new LambdaQueryWrapper<ProdTagReference>()
                    .in(ProdTagReference::getProdId, prodIds));
            //给器赋值
            //对其进行分组
            Map<Long, List<ProdTagReference>> tagMap = tagList.stream().collect(Collectors.groupingBy(ProdTagReference::getProdId));
            records.stream().forEach(prod -> {
                List<ProdTagReference> list = tagMap.get(prod.getProdId());
                List<Long> tag = list.stream().map(ProdTagReference::getTagId).collect(Collectors.toList());
                prod.setTagList(tag);
            });
            //获得商品的全部评论
            List<ProdComm> prodComms = prodCommService.list(new LambdaQueryWrapper<ProdComm>()
                    .in(ProdComm::getProdId, prodIds));
            //对商品id和评论进行分组
            Map<Long, List<ProdComm>> listMap = prodComms.stream().collect(Collectors.groupingBy(ProdComm::getProdId));
            //赋值操作
            records.stream().forEach(prod -> {
                //获取到某一个商品的所有评论
                List<ProdComm> comms = listMap.get(prod.getProdId());
                //由于有些商品不存在评论 进行判断
                if (!CollectionUtils.isEmpty(comms)) {
                    //评论总数
                    int total = comms.size();
                    //设置好评数
                    //判断商品是否为好评
                    long goodCount = comms.stream().filter(prodComm -> prodComm.getEvaluate().equals(0)).count();
                    prod.setPraiseNumber(goodCount);
                    //好评率
                    BigDecimal goodLv = new BigDecimal(goodCount).divide(new BigDecimal(total), BigDecimal.ROUND_HALF_UP)
                            .multiply(new BigDecimal(100));
                    prod.setPositiveRating(goodLv);
                }
            });

        }
        return records;
    }

    @Override
    public Prod getProdList(Long prodId) {
        List<Sku> list = skuService.list(new LambdaQueryWrapper<Sku>()
                .eq(Sku::getProdId, prodId));
        Prod prod = prodMapper.selectById(prodId);
        prod.setSkuList(list);
        return prod;
    }


    /**
     * 修改库存
     *  1.超库处理  需要加锁
     *    1.查询是否库存是否足够
     *    也可以使用version处理
     *     * select version from prod  #0
     *      * #修改数据库库存 version 版本号只能一个方向变化
     *      * update prod set count = count - #{number} ,version = version +1 where prodId = 1 and  version = 0
     *
     *      基于数据库数量业务字段实现
     *      * #基于数据库库存业务字段实现
     *      * update prod  set actual_total = actual_total - #{number} where prodId =1 and  actual_total - #{number}>=0
     * @param changeDto
     */
    @Override
    @Transactional
    public void changeDBOrder(ChangeDto changeDto) {
        List<EsChange> esChanges = changeDto.getEsChangeList();
        esChanges.stream().forEach(esChange -> {
            prodMapper.changeProdCount(esChange);
        });
        List<SkuChang> skuChangList = changeDto.getSkuChangList();
        skuChangList.stream().forEach(skuChang -> {
            skuService.changeSkuCount(skuChang);
        });
    }


}




